<?php

  // Carga de clases
  require_once ("C_krn_tools.php");
  require_once ("C_krn_exception.php");
  require_once ("C_krn_session.php");
  require_once ("html.class.php");
  require_once ("web.class.php");
  require_once ("C_krn_ApiCrypter.php");
  
  class c_login {
	
	  /* Evitamos el clonaje del objeto. Patrón Singleton */
	  private function __clone() { }
	  
	  private function __wakeup() { }
	  
	  function __construct() {
		
		  // Accedemos a las sesiones
		  global $IDIOMA, $language;
		  global $s;
	    global $cUTIL;
		  global $cAUDIT;
		  global $cHTML_web;
		  global $cNET;
		  global $BD;
	    global $cCRYPT;
	    
		  // Log del constructor
		  $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, "::constructor (" . __CLASS__ . ")" );
		
			// Comprobamos si la petición se hace por GET o POST
			// POST sirve para actualizar datos en el servidor
			// GET sirve para obtener datos del servidor y actualizar la página cliente
			// if (isset ( $_POST[ 'FORM_OPERATION' ] ) ) { $FORM_OPERATION = mysql_real_escape_string( $_POST[ 'FORM_OPERATION' ] ); } else { $FORM_OPERATION = mysql_real_escape_string( $_GET[ 'FORM_OPERATION' ] ); } /* if (isset ( $_POST[ 'CONNECT_MODE' ] ) ) { $FORM_OPERATION = mysql_real_escape_string( $_POST[ 'CONNECT_MODE' ] ); } else { $FORM_OPERATION = mysql_real_escape_string( $_GET[ 'CONNECT_MODE' ] ); }
		
		  if ((!isset($_POST ['CONNECT_MODE'])) || ($_POST ['CONNECT_MODE'] == '')) {
		    // Obtengo el tipo de conexion, movil, table o web
		  	$_POST ['CONNECT_MODE'] = $cUTIL->getDEVICE_VAR ( 0 );
			}
		
		  // Si está definido FORM_OPERATION y CONNECT_MODE podemos continuar
      if (
          (isset($_POST ['FORM_OPERATION']) && $_POST ['FORM_OPERATION'] != '') &&
          (isset($_POST ['CONNECT_MODE']) && $_POST ['CONNECT_MODE'] != '')
         ) {
  	        $FORM_OPERATION = mysql_real_escape_string ( $_POST ['FORM_OPERATION'] );
		        $CONNECT_MODE = mysql_real_escape_string ( $_POST ['CONNECT_MODE'] );
          
          	// Solo se actualizará si se está en modo web ya que via app móvil no hay sessiones como tal dadas de alta.
            $s->setSESSION ( 'SESSION_CONNECT_MODE',  $CONNECT_MODE );
            $s->setSESSION ( 'SESSION_FORM_OPERATION', $FORM_OPERATION );

         		// Variable que se devuelve a la función de ajax
       		  $ret = 0;
       		
         		$cAUDIT->AddAudit ( AUDIT_APP, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [44] . $FORM_OPERATION );
       		  $cAUDIT->AddAudit ( AUDIT_APP, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [34] . $CONNECT_MODE );
       		
       			// Si es una aplicación móvil obtengo el json
       			if (($CONNECT_MODE == CONNECT_MOVIL ) ||
       			    ($CONNECT_MODE == CONNECT_TABLET )) {
       			
       			  global $AC;
       			  // Desencriptamos el json que viene encriptado por la app de android
       			  $json_decripted = $AC->decrypt( $_POST ['JSON_OPERATION'] );

       			
       				$json = json_decode( $json_decripted, TRUE);
 				  	  $email = trim(strtolower($json['INFO_OPERATION']['USERNAME']));
 				  	  
 				  	  // Comprobamos si estoy logueado
       		    $LOGUEADO = (($s->getEstaLogeado ()) || ($s->getEstaLogueadoEnBD ( $email )));
 				  	  
 				  	  $cAUDIT->AddAudit ( AUDIT_APP, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [89] . $cUTIL->JSONprettyPrint ( $json_decripted ) );
						} else	if ($CONNECT_MODE == CONNECT_WEB ) { 
						  // Si es web solo lo anoto

							// Comprobamos si estoy logueado
       		    $LOGUEADO = (($s->getEstaLogeado ()) || ($s->getEstaLogueadoEnBD (  $s->getSESSION ( 'SESSION_EMAIL'  ) ) ) );						    
						   
						  $cAUDIT->AddAudit ( AUDIT_APP, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [92] . $CONNECT_MODE );
       		  } else {
       		    // Si no es web ni app movil error
       		    $LOGUEADO = FALSE;
       		    $cAUDIT->AddAudit ( AUDIT_APP, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [93] . $language [$IDIOMA] [92] . $CONNECT_MODE );
       		  }
						
       		  // Comprobamos si estoy logueado
       		  if ($LOGUEADO) 
       		    $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, "Logueado? TRUE" );
       			else
       		    $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, "Logueado? FALSE" );
       			
       			// Case que nos discrimina las posibles opciones
       			switch ($FORM_OPERATION) {
       			  case "INDEX" :
       			  case "INDEX_FORM_ADMIN" :
       			  case "INDEX_FORM_ABOUT" :
       			    $ret = $cHTML_web->getHTML_web ( $FORM_OPERATION );
       			    break;
       			  case "FORM_LOGIN_AJ_JQ_FIND" :
       			    $email = mysql_real_escape_string ( $_POST ['EMAIL'] );
       			    // devuelve el número de filas. Al buscar un usuario solo debe devolver 1 fila
       				  $ret = $s->SESSION_PROCESO_FIND_USER ( mysql_real_escape_string ( $email ) );
       				  break;
       				case "FORM_LOGIN_AJ_JQ_INTENT_LOGIN" :
       			  case "APP_LOGIN":
       			    /*
       			      -1 -> YA ESTOY LOGUEADO
       			       0 -> ERROR EN PROCESO PROCESO_Login Y SESSION_PROCESO_Login
       			       3 -> USUARIO ACTIVO EN OTRO EQUIPO
       			       4 -> USUARIO INACTIVO ANTES DE LOGUEARSE
       			       5 -> USUARIO BLOQUEADO
       			       6 -> USUARIO PENDIENTE DE ACTIVACIÓN
       			     
       			       El login solo se produce en los estados 3 o 4
       			    */
       			  
       			    // Si venimos de una aplicación web hay que descomponer el json
       			    // El parámetro se envía como POST por la APP de android y se envía en JSON_OPERATION -> INFO_OPERATION -> (USERNAME, PASSWORD);
       			    // El parámetro TRUE es para convertir a array
       			    
       			    if (
       			        ($FORM_OPERATION == 'APP_LOGIN') &&
       			        (
       			         ($CONNECT_MODE == CONNECT_MOVIL) ||
       			         ($CONNECT_MODE == CONNECT_TABLE)
       			        )
       			       ) 
       			    {
       			      // $json --> obtenido antes
       			      // $email --> obtenido antes
       			      $password = $json['INFO_OPERATION']['PASSWORD'];
       			    
       			      // obtenemos el codigo de aplicación del json que envía la app movil
       			      $COD_APLICACION = $json['INFO_APP']['ID_APP'];
       			    
       			      // Registramos la sesion solo cuando nos conectamos con la app movil
       			      $s->RegistrarConexion ( $json );
       			    
       			    } else {
       			      // Si la sesión es vía web, los datos los tenemos en el formulario
       			      $email = mysql_real_escape_string ( $_POST ['EMAIL'] );
       					  $password = mysql_real_escape_string ( $_POST ['PASSWORD'] );
       					  // Si es la web el código de aplicación es 1
       					  $COD_APLICACION = 1;
       			    }
       			  
       			    // Proceso de Login
      				  if ($LOGUEADO) {
       					  // Este fichero es para intentar logearse, si ya lo estoy genero un mensaje de error.
       					  // Antes de permitir entrar porque ya estoy logueado, debemos comprobar que tenemos permisos para entrar	
       					  			
       					  if ($BD->ConfirmarUsuarioDispositivoAplicacion ( $COD_APLICACION, $CONNECT_MODE, $email )) {
       					     $cAUDIT->AddAudit ( AUDIT_APP, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [112] );		  
       					     // Si tengo permisos para entrar y aparte estoy logueado desde otro sitio permito entrar
       					     // Si no tengo permisos para por ejemplo la app_movil pero si estoy logueado desde la web no permito entrar
       					    $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [39] );
       					    $ret = - 1;
       					  } else {
       					    $cAUDIT->AddAudit ( AUDIT_APP, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [113] );		  
       					    // No tengo permisos parar entrar de este modo APP_x pero ya estoy logueado de otro modo
       					    $ret = 0;
       					  }
       				  } else {
       					  $ret = $s->SESSION_PROCESO_Login ( $email, $password, $CONNECT_MODE, $FORM_OPERATION, $COD_APLICACION );
       				  }
       				  $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, "Result LOGIN: " . mysql_real_escape_string($ret) );    			  
       			    break;
       			  case "FORM_LOGOUT" :
       			  case "APP_LOGOUT" :
       		      // Comprobamos si estoy logueado
       		      if ($LOGUEADO) {
       			      if (
       			          ($FORM_OPERATION == 'APP_LOGOUT') &&
       			          (
       			           ($CONNECT_MODE == CONNECT_MOVIL) ||
       			           ($CONNECT_MODE == CONNECT_TABLE)
       			          )
       			         ) 
       			      {
                     // Solo registro la conexion por movil
                     $s->RegistrarConexion ( $json );
									
									   $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [89] . $cUTIL->JSONprettyPrint ( $json_decripted  ) );
       						
       						   $ret = $s->SESSION_PROCESO_Logout ( $email );
       					  }
       					  else {
       					    // Si es web
       					    $ret = $s->SESSION_PROCESO_Logout ( $s->getSESSION ( 'SESSION_EMAIL' ) );
       					    // Si es una APP_MOVIL no entra por este if ya que solo al loguearse por web se crea una variable temporal en la sesión que en APP no existe.
       					    // Cada petición MOVIL es nueva y se pierden las variables de sesión
       				    }
       				  } else {
       					  $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [61] );
       					  $ret = 0;
       				  }
       			    break;
       			  case "APP_LOAD_LISTAS" : 
       			  case "APP_ADD_LIST" : 
       			  	// -1 -> YA ESTOY LOGUEADO
								// 0 -> ERROR EN PROCESO PROCESO_Login o SESSION_PROCESO_Login
								// 3 -> USUARIO ACTIVO EN OTRO EQUIPO
								// 4 -> USUARIO INACTIVO ANTES DE LOGUEARSE
								// 5 -> USUARIO BLOQUEADO
								// 6 -> USUARIO en PENDING_ACTIVATE
								// El login solo se produce en los estados 3 o 4 en la web y
								// en los estado 3, 4 y -1 en APP ya que si estoy logueado como u1
								// por la web y me logueo por la APP me debe de dejar
       		      
       		      // Ponemos este valor por que uno de los que permite loguearse el 3, 4 y -1
       		      $ret = -1;
       		      if (!$LOGUEADO) {
       						// Si no estoy logueado me logueo automaticamente
       					  $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [61] );
       					  
       					  // Si no estoy logueado lo hago automaticamente para refrescar los datos en la BD
       					  $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [97] . $email );
       					  
       				    // $json --> obtenido antes
       			      // $email --> obtenido antes
       			      $password = $json['INFO_OPERATION']['PASSWORD'];
       			      
       			      // obtenemos el codigo de aplicación del json que envía la app movil
       			      $COD_APLICACION = $json['INFO_APP']['ID_APP'];
       			      
									// Logueo automático
									$ret = $s->SESSION_PROCESO_Login ( $email, $password, $CONNECT_MODE, $FORM_OPERATION, $COD_APLICACION );
       				  }
       				  
       				  // Si se puede entrar
       				  if (($ret == 3) || ($ret == 4) || ($ret == -1)) {
       			    	// Registramos la sesion solo cuando nos conectamos con la app movil
       			    	$s->RegistrarConexion ( $json );
									
									// Este case se utiliza para varias cosas
									if ($FORM_OPERATION == "APP_LOAD_LISTAS") {
									
										// Cargar la lista de la compras							
									  $ret = json_encode ( $s->CargarListasDeLaCompra ( $email ), JSON_UNESCAPED_UNICODE );
									  
									} else if ($FORM_OPERATION == "APP_ADD_LIST") {
									
										// Extraigo los datos de JSON
										$shared = $json['INFO_OPERATION']['LIST_SHARED'];
										$name   = $json['INFO_OPERATION']['LIST_NAME'];
										// Añadir una nueva lista de la compra al usuario
									  $ret = json_encode ( $s->CrearNuevaListaCompra ( $email, $name, $shared ), JSON_UNESCAPED_UNICODE );
									
									}									
								
									$cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $ret ); 
									$cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [89] . $cUTIL->JSONprettyPrint ( $ret ) );       						
                } else {
                  // Si hay fallado el login automático
	                $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [96] . $language [$IDIOMA] [96] );       						
                } 
                break;
       			  case "APP_REGISTER_USER" : 
       		      $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [99] . mysql_real_escape_string ( $email ) );
       					  
       				  // $json --> obtenido antes
       			    // $email --> obtenido antes
       			    $password = $json['INFO_OPERATION']['PASSWORD'];
       			      
       			    // Registramos la sesion solo cuando nos conectamos con la app movil
       			    $s->RegistrarConexion ( $json );
       			    
								// Busco el usuario 
								// Esto devuelve el número de filas, al buscar un usuario solo debe devolver 1 fila
								// Si devuelve 1 es que existe el usuario
							  $ret = $s->SESSION_PROCESO_FIND_USER ( mysql_real_escape_string ( $email ) );			  
       				  $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [103] . mysql_real_escape_string ( $email ) . " = " . $ret );       						
                
       				  // Si hay 0 usuarios puedo crear uno nuevo
       				  if ($ret == 0) {
       				    // Crear usuario
       				    $ret = $s->SESSION_Create_User ( mysql_real_escape_string ( $email ), mysql_real_escape_string ( $password ) );
       				    if ($ret == 1) {
       				      // Si todo va bien y ha insertado 1 elemento envio un mail
       				      // Si tengo un dominio pagado 
       				      if (USE_APPLICATION_PAID_DOMAIN) 
       				        $cUTIL->EnviarMail ( mysql_real_escape_string ( $email ), $password, APPLICATION_PAID_DOMAIN . APP_DIR_WEB . "classes/a.php?id=" . $cCRYPT->getCRYPT( mysql_real_escape_string ( $email ) ) , $cNET->getIP_External() );
       				      else
       				        $cUTIL->EnviarMail ( mysql_real_escape_string ( $email ), $password, "http://" . $cNET->getIP_External() . APP_DIR_WEB . "classes/a.php?id=" . $cCRYPT->getCRYPT( mysql_real_escape_string ( $email ) ) , $cNET->getIP_External() );
       				      // Dejo el estado en PENDING_ACTIVATE
       				      $ret = 6;
       				    }
       				    $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [104] . mysql_real_escape_string ( $email ) . " result " . $ret );       						
                  
       				    // Esta función devuelve 6 si todo va bien y está pendiente de activar y -1 si no ha podido insertar
       				  } else {
       				    // En este paso sabemos que el usuario existe
       				    // Vamos a comprobar si está en estado PENDING_ACTIVE o es un usuario existente el que se intenta crear
       	  				// Comprobamos si está bloqueado el usuario
									$campo = $BD->GetCampo( TABLA_USUARIOS, "STATUS", "email", mysql_real_escape_string ( $email ) );
									// Viene del fichero de constantes INACTIVE ACTIVE BLOCKED
		    					$status = unserialize ( LOGIN_STATUS );
		    
		    					// PENDING_ACTIVATE, debo activarlo haciendo click en la url que me ha llegado por correo
		    					if ($campo['STATUS'] == $status[3]) {
		    					  $ret = 6;
		    					   if (USE_APPLICATION_PAID_DOMAIN) 
       				        $cUTIL->EnviarMail ( mysql_real_escape_string ( $email ), $password, APPLICATION_PAID_DOMAIN . APP_DIR_WEB . "classes/a.php?id=" . $cCRYPT->getCRYPT( mysql_real_escape_string ( $email ) ) , $cNET->getIP_External() );
       				      else
       				        $cUTIL->EnviarMail ( mysql_real_escape_string ( $email ), $password, "http://" . $cNET->getIP_External() . APP_DIR_WEB . "classes/a.php?id=" . $cCRYPT->getCRYPT( mysql_real_escape_string ( $email ) ) , $cNET->getIP_External() );
		    					} else
		    					  // devuelvo 1, indicando error, es decir ha encontrado un usuario con ese email.
		    					  $ret = 1;

       				    $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [104] . mysql_real_escape_string ( $email ) . " = DUPLICATED USER ($ret)" );       						
                }  
     				    // Por lo tanto al terminar todo el CASE:
     				    // - Si Es 0 es que NO existe un usuario con ese nombre, por tanto inserto:
     				    //   - La inserción devuelve 1 si ok, la convertimos a 0 para que 0 sea ok
     				    //   - otro valor si falló la inserción
     				    // - Si es otro valor distinto de 0 es que ya esiste       				  
								$cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [99] . mysql_real_escape_string ( $email ) . " = " . $ret );       						
                break;
       			  default :
       				  $cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [77] . "Operation: " . $FORM_OPERATION . " - Connect Mode: " . $CONNECT_MODE );
       			  }
       		
       		  // En la variable $ret se supone que está el codigo html necesario
       		  // hay que poner un echo no un return para que el javascript ajax lo interprete correctamente
       		  echo $ret;
       		  // Si es una app movil lo que voy a devolver es un json
       		  // r={return_code=X,error_code=X,return_sms="xxx"}
       		  // Si no es una app devolveré un valor para que el resto de la app web la interprete correctamente ya que sobre todo esperan valores 
       		  // numéricos 1,2,3 ....
			} else {
				// No se puede continuar sin las variables definidas
     		$cAUDIT->AddAudit ( AUDIT_APP, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, __CLASS__ . " :: " . $language [$IDIOMA] [88] );
			}			  
	  }
	
	private static $_instance;
	public static function getInstance() {
		if (! (self::$_instance instanceof self)) {
			self::$_instance = new self ();
		}
		return self::$_instance;
	}
}


// Instancia de la clase
try {
	$cPROC = c_login::getInstance ();
} catch ( Exception $e ) {
	global $cAUDIT;
	global $IDIOMA, $language;
	
	$cAUDIT->AddAudit ( AUDIT_EXTEND, __DIR__, __FILE__, __LINE__, __CLASS__, __METHOD__, __FUNCTION__, $language [$IDIOMA] [2] . $e->getMessage () );
}

?>
